#pragma once
#pragma comment(lib, "ws2_32.lib")
#include <stdint.h>

#define RTP_VERSION 2

#define RTP_PAYLOAD_TYPE_H264 96
#define RTP_PAYLOAD_TYPE_AAC 97

#define RTP_HEADER_SIZE 12
#define RTP_MAX_PKT_SIZE 1400

/*
 *    0                   1                   2                   3
 *    7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |V=2|P|X|  CC   |M|     PT      |       sequence number         |
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |                           timestamp                           |
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |           synchronization source (SSRC) identifier            |
 *   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
 *   |            contributing source (CSRC) identifiers             |
 *   :                             ....                              :
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 */
// RTP的标识头
struct RtpHeader
{
	// tip：位域是从低位开始填充
	/* byte 0 */
	uint8_t csrcLen : 4;	//CSRC计数器，占4位，指示CSRC 标识符的个数。[本项目用不到，故等会直接赋值为0]
	uint8_t extension : 1;	//占1位，如果X=1，则在RTP报头后跟有一个扩展报头。
	uint8_t padding : 1;	//填充标志，占1位，如果P=1，则在该报文的尾部填充一个或多个额外的八位组，它们不是有效载荷的一部分。
	uint8_t version : 2;	//RTP协议的版本号，占2位，当前协议版本号为2。

	/* byte 1 */
	uint8_t payloadType : 7;//有效载荷类型，占7位，用于说明RTP报文中有效载荷的类型，如GSM音频、JPEM图像等。
	uint8_t marker : 1;		//标记，占1位，不同的有效载荷有不同的含义，对于视频，标记一帧的结束；对于音频，标记会话的开始。

	/* byte 2,3 */
	uint16_t seq;			//占16位，用于标识发送者所发送的RTP报文的序列号，每发送一个报文，序列号增1。接收者通过序列号来检测报文丢失情况，重新排序报文，恢复数据。

	/* byte 4-7 */
	uint32_t timestamp;		//占32位，时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动，并进行同步控制。

	/* byte 8-11 */
	uint32_t ssrc;			//占32位，用于标识同步信源。该标识符是随机选择的，参加同一视频会议的两个同步信源不能有相同的SSRC。

	/*
	* 标准的RTP Header 还可能存在 0-15个特约信源(CSRC)标识符
	* 每个CSRC标识符占32位，可以有0～15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源
	* [但是我们项目确定用不到这个字段，csrcLen 直接赋值为0，故这个字段可以直接不写，反正也不给]
	*/
	//uint32_t csrc[15];
};

// 一个完整的RTP包请求数据
struct RtpPacket
{
	struct RtpHeader rtpHeader;//标识头
	uint8_t payload[0]; //载荷数据
};

// 给rtpPacket添加标识头信息
void rtpHeaderInit(struct RtpPacket* rtpPacket, uint8_t version, uint8_t padding, uint8_t extension,
					uint8_t csrcLen, uint8_t marker, uint8_t payloadType, uint16_t seq,
					uint32_t timestamp, uint32_t ssrc);
// 通过TCP方式发送RTP包数据[此时使用的是TRSP的套接字端口]
int rtpSendPacketOverTcp(int clientSockfd, struct RtpPacket* rtpPacket, uint32_t dataSize);
// 通过UDP方式发送RTP包数据
int rtpSendPacketOverUdp(int serverRtpSockfd, const char *ip, int16_t port, struct RtpPacket* rtpPacket, uint32_t dataSize);
